iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
Mobile Development

ios 的小小實驗室 2 !!系列 第 25

實作 UserDefaults、客製化 NavigationBar

  • 分享至 

  • xImage
  •  

利用 前天的 UserPreferences 再加上昨天的 客製化 NavigationBar 實作出的成品:


  1. 宣告 UserDefaults 的部分

    import Foundation
    
    class UserPreferences {
    
    	static let shared = UserPreferences()
    
    	private let userPreference: UserDefaults
    
    	private init() {
    		// 設定要儲存的值(value) 及 key
    		userPreference = UserDefaults.standard
    	}
    
    	enum UserPreference: String {
    		case numIndex   // 顯示在 SecondViewController 的數值
    	}
    
    	var numIndex: String {
    		get { return userPreference.string(forKey: UserPreference.numIndex.rawValue) ?? "0" }
    		set { userPreference.set(newValue, forKey: UserPreference.numIndex.rawValue) }
    	}
    }
    
  2. 寫一個 BaseViewController,裡面可以寫常用的 function

    import Foundation
    import UIKit
    class BaseViewController: UIViewController {
    
    	// MARK: - NavigationController.push
    
    	/// NavigationController.pushViewController 跳頁 (不帶 Closure)
    	/// - Parameters:
    	///   - viewController: 要跳頁到的 UIViewController
    	///   - animated: 是否要換頁動畫,預設為 true
    	public func pushViewController(_ viewController: UIViewController, animated: Bool = true) {
    		if let navigationController = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.rootViewController as? UINavigationController {
    			navigationController.pushViewController(viewController, animated: animated)
    		}
    	}
    
    	/// NavigationController.pushViewController 跳頁 (帶 Closure)
    	/// - Parameters:
    	///   - viewController: 要跳頁到的 UIViewController
    	///   - animated: 是否要換頁動畫
    	///   - completion: 換頁過程中,要做的事
    	public func pushViewController(_ viewController: UIViewController, animated: Bool, completion: @escaping () -> Void) {
    		self.navigationController?.pushViewController(viewController, animated: animated)
    		guard animated, let coordinator = transitionCoordinator else {
    			DispatchQueue.main.async { completion() }
    			return
    		}
    		coordinator.animate(alongsideTransition: nil) { _ in completion() }
    	}
    
    	// MARK: - NavigationController.pop
    
    	/// NavigationController.popViewController 回上一頁 (不帶 Closure)
    	/// - Parameters:
    	///   - animated: 是否要換頁動畫,預設為 true
    	public func popViewController(_ animated: Bool = true) {
    		self.navigationController?.popViewController(animated: animated)
    	}
    
    	/// NavigationController.popViewController 回上一頁 (帶 Closure)
    	/// - Parameters:
    	///   - animated: 是否要換頁動畫
    	///   - completion: 換頁過程中,要做的事
    	public func popViewController(animated: Bool, completion: @escaping () -> Void) {
    		self.navigationController?.popViewController(animated: animated)
    		guard animated, let coordinator = transitionCoordinator else {
    			DispatchQueue.main.async { completion() }
    			return
    		}
    		coordinator.animate(alongsideTransition: nil) { _ in completion() }
    	}
    }
    
  3. 個別新增第一頁、第二頁

    • 第一頁(MainViewController):

      mport UIKit
      
      / 將 MainViewController 的型態設為 BaseViewController
      lass MainViewController: BaseViewController {
      
      override func viewDidLoad() {
      	super.viewDidLoad()
      }
      
      @IBAction func touchUpInside(_ sender: UIButton) {
      	// 宣告下一頁為 SecondViewController
      	let nextVC = SecondViewController()
      	self.pushViewController(nextVC, animated: false)
      }
      
      ``
      
      
    • 第二頁(SecondViewController):

      mport UIKit
      
      / 將 SecondViewController 的型態設為 BaseViewController
      lass SecondViewController: BaseViewController {
      
      @IBOutlet weak var numLabel: UILabel!
      
      var index = UserPreferences.shared.numIndex
      
      // MARK: - LifeCycle
      
      override func viewDidLoad() {
      	super.viewDidLoad()
      	setupUI()
      }
      
      // MARK: - UI Initial Setup
      
      func setupUI() {
      	setupLeftAndRightNavigationBarItems()
      	numLabel.text = index
      }
      
      // MARK: - 客製化 NavigationBar
      
      /// CustomizationNavigationBarItems
      /// - Parameters:
      ///   - LeftNavigationBarItems: 返回鍵
      ///   - RightNavigationBarItems: 加1、減1、歸零
      private func setupLeftAndRightNavigationBarItems() {
      
      	// MARK: - Left NavigationBarItems 由左至右
      
      	let backButton = UIButton(type: .system)
      
      	backButton.setImage(UIImage(systemName: "chevron.left"), for: .normal)
      
      	backButton.setTitle("返回鍵", for: .normal)
      
      	// 新增返回鍵被點擊後的觸發事件
      	backButton.addTarget(self, action: #selector(self.backButtonAction), for: .touchUpInside)
      
      	self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)
      
      	// MARK: - Right NavigationBarItems 由右至左
      
      	let valuePlus = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(valuePlusOneObjc))
      
      	let valueMinus = UIBarButtonItem(image: UIImage(systemName: "minus"), style: .done, target: self, action: #selector(valueMinusOneObjc))
      
      	let valueZero = UIBarButtonItem(image: UIImage(systemName: "clear"), style: .done, target: self, action: #selector(valueToZeroObjc))
      
      	self.navigationItem.rightBarButtonItems = [valuePlus, valueMinus, valueZero]
      }
      
      /// 數值運算
      private func valueChange(calculation: String){
      
      	switch calculation{
      
      	/// 數值加一
      	case "plus":
      		index = "\(Int(index)! + 1)"
      		numLabel.text = index
      		UserPreferences.shared.numIndex = index
      
      	/// 數值減一
      	case "minus":
      		index = "\(Int(index)! - 1)"
      		numLabel.text = index
      		UserPreferences.shared.numIndex = index
      
      	/// 數值歸零
      	case "clear":
      		index = "0"
      		numLabel.text = index
      		UserPreferences.shared.numIndex = index
      
      	default:
      		break
      	}
      }
      
      // MARK: - Right NavigationBarItems Function
      
      @objc func backButtonAction() {
      	popViewController(false)
      }
      
      @objc func valuePlusOneObjc() {
      	valueChange(calculation: "plus")
      }
      
      @objc func valueMinusOneObjc() {
      	valueChange(calculation: "minus")
      }
      
      @objc func valueToZeroObjc() {
      	valueChange(calculation: "clear")
      }
      
      ``
      
      

大功告成!可以參考 GitHub - SetupNavigationBarItemsDemo


上一篇
客製化 NavigationBar
下一篇
關於 SpriteKit 基本元件介紹 1
系列文
ios 的小小實驗室 2 !!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言